﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MWS.Contracts.Caching.V1;
using MWS.Contracts.Resource.V1.Models;
using MWS.Contracts.Resource.V1.Interfaces;
using MWS.Contracts.Resource.V1.Messages;
using MWS.Contracts.Service.V1.Models;
using MWS.Processing.Interfaces;
using Resource = MWS.Contracts.Resource.V1.Models.Resource;

namespace MWS.Processing.Trackers
{
    public class ResourceRequestTracker : IRequestTracker 
    {
        private readonly IResourceService resourceService;
        private readonly string namespaceUri;

        public TimeSpan TrackingWindow { get; set; }

        public ResourceRequestTracker(
            IResourceService resourceService, 
            TimeSpan trackingWindow, 
            string namespaceUri = "ns:indexing")
        {
            TrackingWindow = trackingWindow;
            this.resourceService = resourceService;
            this.namespaceUri = namespaceUri;
        }

        public void RecordRequests(IList<string> requestKeys)
        {
            // First we delete the request keys so we dont end up with multiple assertions 
            // for this request that have different "lastIndexed" times.
            resourceService.DeleteResources(
                new DeleteResourcesRequest
                    {
                        ResourceUris = requestKeys
                    });


            resourceService.PutResources(
                new PutResourcesRequest
                    {
                        Resources = requestKeys
                            .Select(rk =>
                                    new Resource
                                        {
                                            ResourceUri = rk,
                                            ValueStatements =
                                                new List<ValueStatement>
                                                    {
                                                        new ValueStatement
                                                            {
                                                                NamespaceUri = namespaceUri,
                                                                PredicateUri = "indexing:lastIndexed",
                                                                ObjectType = DataType.DateTime,
                                                                ObjectValue = DateTime.UtcNow.ToString()
                                                            }
                                                    }
                                        }).ToList()
                    });
        }

        public IDictionary<string, DateTime> GetRequests(TimeSpan timeFilter)
        {
            var resources = resourceService.SearchResources(
                new SearchResourcesRequest
                    {
                        Filter = new ValueStatementFilter
                                     {
                                         StatementSection = StatementSection.Subject,
                                         Operator = Operator.GreaterThanOrEqualTo,
                                         Statement = new ValueStatement
                                                         {
                                                             NamespaceUri = namespaceUri,
                                                             PredicateUri = "indexing:lastIndexed",
                                                             ObjectValue =
                                                                 DateTime.UtcNow.Subtract(timeFilter).ToString()
                                                         }
                                     },
                            PagingContext = new PagingContext
                                                {
                                                    ResultsPerPage = 10000
                                                }
                    }).Resources;

            var requests = resources
                .SelectMany(resource => resource.ValueStatements)
                .ToDictionary(valueStatement => valueStatement.SubjectUri, valueStatement => DateTime.Parse(valueStatement.ObjectValue));

            return requests;
        }
    }
}
